/*HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 H       io_device.h
 H       Application name: tcss422-project2
 H       Programmers names:	Evan Phillips, Lucas Cowell, Tony Butterfield
 H       Date created:	May 13, 2011
 H       Date completed: 
 H       Brief Description: simulated generic io device.  When it recieves an io request, it will
 H                  return an io interrupt after a random interval.
 H
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH*/

#ifndef IO_DEVICE_H_
#define IO_DEVICE_H_
#endif /* IO_DEVICE_H_ */

/* FORWARD DEFINITIONS - resolves circular dependencies */
struct process_queue_str;       // forward definition of a process queue
struct cpu_str;                 // forward definitiion of cpu struct (for returning IO_INTERRUPT)

/***************************************************************************************************
 *  ADT: IO device
 *  Description:  A simulation of a generic IO device that can be used to create the video and disc
 *              simulation.  The Keyboard IO device will need to be built differently.
 *
 *              As with the Process, in a multi-threaded simulation, the IO device would
 *              be a counter that would, when called, count a random interval and return an
 *              IO_INTERRUPT, then go back to sleep until recalled.
 *
 *              In this single-threaded simulation, the main process has to do the counting for the
 *              the CPU, the system clock,  and each IO device.
 *
 *              While the CPU would be directly counting the Process' instruction steps, we should
 *              simulate the asynchronous nature of the IO device by generating a random number of
 *              system clock ticks as the interval between request and interrupt.
 *
 *
 *
 *  Implementation:  Uses a struct to store data to be used by the main process, as well as an
 *              instance of a process queue and a counter to be incremented by the simulated
 *              system clock.
 *
 ***************************************************************************************************/

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 $ Typedefs
 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
typedef struct io_device_str
{
        int clock_counter;                      // clock counter
        int working;                            // clock ticks until IO_INTERRUPT is generated
        int io_interrupt;                       // specific interrupt returned by this device
        struct process_queue_str* blocked_q;    // this devices blocked process queue
        struct cpu_str* cpu;                    // pointer back to the cpu
} IODeviceStr;
typedef IODeviceStr* IODevice;

/*-------------------------------------------------------------------------------------------------
 - Prototypes
 -      Initialize - create an new io_device.
 -      Terminate - deallocates memory allocated in Initialize.
 -      Tick - increments internal clock counter then checks work interval. -
 -      Set Request - when a process generates an IO_REQUEST, this function will generate a random
 -                      work interval and initialize the clock counter back to zero.
 -      Throw Interrupt - if clock counter equals the interval, sends an IO_INTERRUPT to the CPU and
 -                      sets work interval back to zero.
 ---------------------------------------------------------------------------------------------------*/
IODevice    iodev_init(int, struct cpu_str*, int*); // allocate memory for IODevice and ProcessQueue
int         iodev_free(IODevice);                   // deallocate mem.
int         iodev_tick(IODevice);                   // called by the system clock
int         iodev_setRequest(IODevice);             // triggered by running Process
int         iodev_throwInterrupt(IODevice);         // send device interrupt to the CPU
